import ctypes
from ctypes import Structure, c_uint8, c_uint16, c_float, c_uint32

class CmdData(Structure):
    """传感器数据结构体"""
    _pack_ = 1
    _fields_ = [
        ('aabbccdd', c_uint32),
        ('reserver', c_uint32),
        ('header', c_uint8),
        ('control', c_uint8),
        ('id1', c_uint8),
        ('id2', c_uint8),
        ('id3', c_uint8),
        ('id4', c_uint8),
        ('id5', c_uint8),
        ('id6', c_uint8),
        ('id7', c_uint8),
        ('id8', c_uint8),
        ('id9', c_uint8),
        ('data', c_uint8*1024),
        ('checksum', c_uint8),
        ('invalid', c_uint8),
        ('tail', c_uint8),
        ('ddccbbaa', c_uint32)
    ]

class SensorCommand:
    """传感器命令封装类"""
    
    # 固定值定义
    FIXED_HEADER = 0xAB
    FIXED_INVALID = 0x00
    FIXED_TAIL = 0xBA
    FIXED_AA_BB_CC_DD = 0xDDCCBBAA
    FIXED_DD_CC_BB_AA = 0xAABBCCDD
    FIXED_RESERVER = 0x00000000
    
    def __init__(self):
        self.cmd_data = CmdData()
        self._set_fixed_values()
    
    def _set_fixed_values(self):
        """设置所有固定值"""
        self.cmd_data.aabbccdd = self.FIXED_AA_BB_CC_DD
        self.cmd_data.reserver = self.FIXED_RESERVER
        self.cmd_data.header = self.FIXED_HEADER
        self.cmd_data.invalid = self.FIXED_INVALID
        self.cmd_data.tail = self.FIXED_TAIL
        self.cmd_data.ddccbbaa = self.FIXED_DD_CC_BB_AA
        
        # 初始化数据区域为零
        for i in range(1024):
            self.cmd_data.data[i] = 0x00
    
    def set_control(self, control_value):
        """设置控制字段"""
        self.cmd_data.control = control_value
    
    def set_ids(self, id_list):
        """设置ID字段"""
        ids = [self.cmd_data.id1, self.cmd_data.id2, self.cmd_data.id3,
               self.cmd_data.id4, self.cmd_data.id5, self.cmd_data.id6,
               self.cmd_data.id7, self.cmd_data.id8, self.cmd_data.id9]
        
        for i, id_value in enumerate(id_list[:9]):
            if i == 0:
                self.cmd_data.id1 = id_value
            elif i == 1:
                self.cmd_data.id2 = id_value
            elif i == 2:
                self.cmd_data.id3 = id_value
            elif i == 3:
                self.cmd_data.id4 = id_value
            elif i == 4:
                self.cmd_data.id5 = id_value
            elif i == 5:
                self.cmd_data.id6 = id_value
            elif i == 6:
                self.cmd_data.id7 = id_value
            elif i == 7:
                self.cmd_data.id8 = id_value
            elif i == 8:
                self.cmd_data.id9 = id_value
    
    def set_data(self, data_bytes, offset=0):
        """设置数据区域"""
        if offset + len(data_bytes) > 1024:
            raise ValueError("数据超出1024字节限制")
        
        for i, byte in enumerate(data_bytes):
            self.cmd_data.data[offset + i] = byte
    
    def calculate_checksum(self):
        """计算校验和"""
        # 计算从header到data结束的所有字节的和
        checksum_data = bytearray(ctypes.string_at(
            ctypes.byref(self.cmd_data.header), 
            ctypes.sizeof(c_uint8) * (9 + 1) + ctypes.sizeof(c_uint8 * 1024)  # header + IDs + data
        ))
        
        return sum(checksum_data) & 0xFF
    
    def update_checksum(self):
        """更新校验和字段"""
        self.cmd_data.checksum = self.calculate_checksum()
    
    def to_bytes(self):
        """转换为字节序列"""
        self.update_checksum()
        return bytes(bytearray(ctypes.string_at(ctypes.byref(self.cmd_data), ctypes.sizeof(self.cmd_data))))
    
    def from_bytes(self, data):
        """从字节序列解析"""
        if len(data) < ctypes.sizeof(CmdData):
            raise ValueError("数据长度不足")
        
        self.cmd_data = CmdData.from_buffer_copy(data)
        return self
    
    def verify_checksum(self):
        """验证校验和"""
        calculated = self.calculate_checksum()
        return calculated == self.cmd_data.checksum
    
    def verify_fixed_values(self):
        """验证固定值是否正确"""
        return (self.cmd_data.aabbccdd == self.FIXED_AA_BB_CC_DD and
                self.cmd_data.reserver == self.FIXED_RESERVER and
                self.cmd_data.header == self.FIXED_HEADER and
                self.cmd_data.invalid == self.FIXED_INVALID and
                self.cmd_data.tail == self.FIXED_TAIL and
                self.cmd_data.ddccbbaa == self.FIXED_DD_CC_BB_AA)
    
    def print_structure(self):
        """打印结构体信息"""
        print(f"结构体大小: {ctypes.sizeof(self.cmd_data)} 字节")
        print(f"固定值验证: {'通过' if self.verify_fixed_values() else '失败'}")
        print(f"校验和验证: {'通过' if self.verify_checksum() else '失败'}")
        print(f"AA BB CC DD: 0x{self.cmd_data.aabbccdd:08X}")
        print(f"Reserver: 0x{self.cmd_data.reserver:08X}")
        print(f"Header: 0x{self.cmd_data.header:02X}")
        print(f"Control: 0x{self.cmd_data.control:02X}")
        print(f"IDs: {self.cmd_data.id1:02X} {self.cmd_data.id2:02X} {self.cmd_data.id3:02X} "
              f"{self.cmd_data.id4:02X} {self.cmd_data.id5:02X} {self.cmd_data.id6:02X} "
              f"{self.cmd_data.id7:02X} {self.cmd_data.id8:02X} {self.cmd_data.id9:02X}")
        print(f"Checksum: 0x{self.cmd_data.checksum:02X}")
        print(f"Invalid: 0x{self.cmd_data.invalid:02X}")
        print(f"Tail: 0x{self.cmd_data.tail:02X}")
        print(f"DD CC BB AA: 0x{self.cmd_data.ddccbbaa:08X}")